import 'package:sleep/db/merroy_db.dart';
import 'package:sleep/single/point_model.dart';

class PluseShowModel extends WaveModel {
  final double bpm;
  final double time;
  final double pPT;
  final double rWTT;
  double? hrv;

  PluseShowModel(
    this.time,
    this.bpm,
    this.pPT,
    this.rWTT,
  );

  static PluseShowModel? fromWave(List<PulseWaveModel> modeles) {
    //汇总成一个数据
    //bpm 求平均
    List<double> times = [];
    List<double> pPTes = [];
    List<double> rWTTes = [];
    for (final model in modeles) {
      times.add(model.time);
      if (model.isStandard) {
        pPTes.add(model.pPT()!);
        rWTTes.add(model.rWTT()!);
      }
    }
    if (pPTes.isEmpty) return null;
    final avergetime =
        times.reduce((value, time) => value + time) / times.length;
    final ppt = pPTes.reduce((value, time) => value + time) / pPTes.length;
    final rwtt = rWTTes.reduce((value, time) => value + time) / pPTes.length;
    return PluseShowModel(avergetime, 60 / avergetime, ppt, rwtt);
  }

  static List<String> toSleepKey() {
    return ['BPM', 'HRV', 'SI', 'PWV'];
  }

  List<String> toSleepValue() {
    final height = MerroyDB.share().height;
    final l = MerroyDB.share().l;

    final si = ((height ?? 0) / pPT).toStringAsFixed(2);

    final pwv = (1.6 * (l ?? 0) / rWTT).toStringAsFixed(2);
    return [bpm.toStringAsFixed(0), hrv?.toStringAsFixed(2) ?? "-", si, pwv];
  }

  static List<String> toFKey() {
    return ['BPM', 'HRV'];
  }

  List<String> toFValue() {
    return [
      bpm.toStringAsFixed(0),
      hrv?.toStringAsFixed(2) ?? "-",
    ];
  }
}

class FtaigueShowData extends WaveModel {
  final double bf;
  final double bd;
  final double perclose;
  final double ct;
  final double vhight;

  FtaigueShowData(
      {required this.bf,
      required this.bd,
      required this.perclose,
      required this.vhight,
      required this.ct});

  static FtaigueShowData? fromWave(List<FatigueWave> modeles) {
    if (modeles.length <= 1) return null;
    //汇总成一个数据
    //bpm 安权重求值  最新值占比 80%
    List<double> timees = [];
    List<double> bdes = [];
    List<double> bfes = [];
    List<double> preclose = [];
    List<double> vhes = [];

    for (final model in modeles) {
      if (model.isStand()) {
        timees.add(model.ct());
        bfes.add(model.bf()!);
        bdes.add(model.bd());
        preclose.add(model.perclose()!);
        vhes.add(model.vhight());
      }
    }

    if (timees.isEmpty) return null;
    if (timees.length == 1) {
      return FtaigueShowData(
          bf: bfes.first,
          bd: bdes.first,
          perclose: preclose.first,
          vhight: vhes.first,
          ct: timees.first);
    }

    final time = timees
                .sublist(0, timees.length - 1)
                .fold(0.0, (pre, e) => pre + e / (timees.length - 1)) *
            0.5 +
        timees.last * 0.5;
    final bd = bdes
                .sublist(0, bdes.length - 1)
                .fold(0.0, (pre, e) => pre + e / (bdes.length - 1)) *
            0.5 +
        bdes.last * 0.5;
    final preclos = preclose
                .sublist(0, preclose.length - 1)
                .fold(0.0, (pre, e) => pre + e / (preclose.length - 1)) *
            0.5 +
        preclose.last * 0.5;
    final bf = bfes
                .sublist(0, bfes.length - 1)
                .fold(0.0, (pre, e) => pre + e / (bfes.length - 1)) *
            0.5 +
        bfes.last * 0.5;

    final vh = vhes
                .sublist(0, vhes.length - 1)
                .fold(0.0, (pre, e) => pre + e / (vhes.length - 1)) *
            0.5 +
        vhes.last * 0.5;

    return FtaigueShowData(
        bf: bf, bd: bd, perclose: preclos, ct: time, vhight: vh);
  }

  static List<String> toKey() {
    return ['BF', 'BD', 'CT', 'PERCLOS'];
  }

  List<String> toValue() {
    return [
      bf.toStringAsFixed(0),
      bd.toStringAsFixed(2),
      (60 / bf).toStringAsFixed(2),
      perclose.toStringAsFixed(2),
    ];
  }
}

class SleepShowData extends WaveModel {
  final double rr; //呼吸频率
  final double t1; //呼吸时间
  final double at; //呼吸暂停时间
  final double ri;
  final double time;
  final double vhight;
  SleepShowData({
    required this.rr,
    required this.vhight,
    required this.t1,
    required this.at,
    required this.ri,
    required this.time,
  });

  static SleepShowData? fromWave(List<SleepWave> modeles, double? standValue) {
    if (modeles.length <= 1) return null;
    //汇总成一个数据
    //bpm 安权重求值  最新值占比 80%
    List<double> rres = [];
    List<double> t1es = [];
    List<double> ates = [];
    List<double> ries = [];
    List<double> timees = [];

    List<double> vhes = [];
    for (final model in modeles) {
      if (model.isStand()) {
        rres.add(model.pr()!);
        t1es.add(model.t1()!);
        ates.add(model.st());
        ries.add((model.vhight() / (standValue ?? 1)) * 100);
        timees.add(model.time());
        vhes.add(model.vhight());
      }
    }

    if (rres.isEmpty) return null;
    if (rres.length == 1) {
      return SleepShowData(
          vhight: vhes.first,
          rr: rres.first,
          t1: t1es.first,
          at: ates.first,
          ri: ries.first,
          time: timees.first);
    }

    final rr = rres
                .sublist(0, rres.length - 1)
                .fold(0.0, (pre, e) => pre + e / (rres.length - 1)) *
            0.5 +
        rres.last * 0.5;
    final t1 = t1es
                .sublist(0, t1es.length - 1)
                .fold(0.0, (pre, e) => pre + e / (t1es.length - 1)) *
            0.5 +
        t1es.last * 0.5;
    final at = ates
                .sublist(0, ates.length - 1)
                .fold(0.0, (pre, e) => pre + e / (ates.length - 1)) *
            0.5 +
        ates.last * 0.5;
    final ri = ries
                .sublist(0, ries.length - 1)
                .fold(0.0, (pre, e) => pre + e / (ries.length - 1)) *
            0.5 +
        ries.last * 0.5;

    final time = timees
                .sublist(0, timees.length - 1)
                .fold(0.0, (pre, e) => pre + e / (timees.length - 1)) *
            0.5 +
        timees.last * 0.5;

    final vh = vhes
                .sublist(0, vhes.length - 1)
                .fold(0.0, (pre, e) => pre + e / (vhes.length - 1)) *
            0.5 +
        vhes.last * 0.5;

    return SleepShowData(
        rr: rr, t1: t1, at: at, ri: ri, time: time, vhight: vh);
  }

  bool isRealSt() {
    if (at > 10) return true;
    return false;
  }

  isLowRi() {
    return ri < 0.5;
  }

  static List<String> toKey() {
    return ['RR', 'T1', 'AT', 'RI'];
  }

  List<String> toValue() {
    final prStr = rr.toStringAsFixed(1);

    final t1Str = t1.toStringAsFixed(1);
    final stStr = at.toStringAsFixed(1);

    final riStr = ri.toStringAsFixed(0);
    return [prStr, t1Str, stStr, riStr];
  }
}
